package com.xiyuan.smartutils.crypto;

import com.xiyuan.smartutils.Asserts;
import com.xiyuan.smartutils.Hexs;
import com.xiyuan.smartutils.Systems;
import com.xiyuan.smartutils.constants.CodeConstants;
import com.xiyuan.smartutils.reflect.Unsafe;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.MessageDigest;

/**
 * SHA256编码，调用JDK的MD5编码
 *
 * @version v1.0.0 @author lgz 2017-8-27 新建与整理
 */
public class SHA256 implements CodeConstants {
    static {
        Unsafe.init();
    }
    
    /**
     * SHA256 编码，UTF-8
     *
     * @param src 源串
     * @return 目标串
     */
    public static String encodeUTF8(String src) {
        return encode(src, _UTF_8_C_);
    }
    
    /**
     * SHA256编码，指定encoding
     *
     * @param src      源串
     * @param encoding 编码
     * @return 目标串
     */
    public static String encode(String src, String encoding) {
        byte[] destBytes = encrypt(src, encoding);
        return Hexs.toHexString(destBytes);
    }
    
    /**
     * SHA1编码，指定charset
     *
     * @param src     源串
     * @param charset 字符串
     * @return 目标串
     */
    public static String encode(String src, Charset charset) {
        byte[] destBytes = encrypt(src, charset);
        return Hexs.toHexString(destBytes);
    }
    
    
    /**
     * SHA1编码,返回byte数组
     *
     * @param src      源串
     * @param encoding 编码
     * @return 目标字节数组
     */
    public static byte[] encrypt(String src, String encoding) {
        Asserts.nonNull(src, _SRC_);
        Asserts.nonNull(encoding, _ENCODING_);
        
        try {
            return encrypt(src.getBytes(encoding));
        }
        catch (UnsupportedEncodingException e) {
            throw Asserts.exception("非法的编码");
        }
    }
    
    
    /**
     * SHA1编码,返回byte数组
     *
     * @param src     源串
     * @param charset 字符集
     * @return 目标字节数组
     */
    public static byte[] encrypt(String src, Charset charset) {
        Asserts.nonNull(src, _SRC_);
        Asserts.nonNull(charset, _CHARSET_);
        
        return encrypt(src.getBytes(charset));
    }
    
    /**
     * SHA1编码,返回byte数组
     *
     * @param src 源byte数组
     * @return 目标编码
     */
    public static byte[] encrypt(byte[] src) {
        Asserts.nonNull(src, _SRC_);
        return getInstance().digest(src);
    }
    
    /**
     * 获取SHA1消息摘要实例
     *
     * @return SHA1消息摘要实例
     */
    public static MessageDigest getInstance() {
        try {
            return MessageDigest.getInstance(_SHA256_);
        }
        catch (Exception e) {
            throw Asserts.exception("JDK不支持[" + _SHA256_ + "]算法");
        }
    }
}
